package biz

import (
	"net/http"
	"server/base"
	"server/base/db"
	"server/biz/cache"
	"server/biz/proto"
	"time"
)

func GetCookie(token string) *cache.CookieValue {
	var cv *cache.CookieValue
	cache.CookieKey(token).Get().Unmarshal(&cv)
	return cv
}

func SetCookie(token string, cv *cache.CookieValue) {
	key := cache.CookieKey(token)
	key.Set(cv)
}

func GetCookieUserId(req *http.Request) int {
	c, _ := req.Cookie("token")
	if c != nil {
		token := c.Value
		cv := GetCookie(token)
		if cv != nil {
			return cv.UserId
		}
	}
	return 0
}

type UserRaw struct {
	Id     int
	OpenId string
	Name   string
	Photo  string
}

func (u *UserRaw) TL() *proto.User {
	out := &proto.User{
		Id:     u.Id,
		Openid: u.OpenId,
		Name:   u.Name,
		Photo:  u.Photo,
	}
	return out
}

func CreateUser(raw *UserRaw) int {
	now := int(time.Now().Unix())
	r := db.Primary.Exec(`insert into user set openid=?, name=?, photo=?, created_at=?`,
		raw.OpenId, raw.Name, raw.Photo, now)
	raw.Id = int(r.LastInsertId())
	return raw.Id
}

func UpdateUser(raw *UserRaw) {
	db.Primary.Exec(`update user set name=?, photo=? where id=?`,
		raw.Name, raw.Photo, raw.Id)
}

func GetUserByOpenid(openid string) *UserRaw {
	if openid == "" {
		return nil
	}
	var o = &UserRaw{}
	ok := db.Replica.QueryRowx(`select id, name, photo from user where openid=?`, openid).Scan(
		&o.Id, &o.Name, &o.Photo)
	if !ok {
		return nil
	}
	o.OpenId = openid
	return o
}

func GetUser(id int) *UserRaw {
	if id == 0 {
		return nil
	}
	var o = &UserRaw{}
	ok := db.Replica.QueryRowx(`select openid, name, photo from user where id=?`, id).Scan(
		&o.OpenId, &o.Name, &o.Photo)
	if !ok {
		return nil
	}
	o.Id = id
	return o
}

func CheckWxUser(openid, name, photo string) *UserRaw {
	user := GetUserByOpenid(openid)
	if user == nil {
		user = &UserRaw{
			Name:   name,
			OpenId: openid,
			Photo:  photo,
		}
		CreateUser(user)
	} else if user.Name != name || user.Photo != photo {
		user.Name = name
		user.Photo = photo
		UpdateUser(user)
	}

	return user
}

// 注册/登陆, set-token
func SignIn(user *UserRaw, w http.ResponseWriter) {
	token := base.RandDigitCode(16)
	now := time.Now()
	key := cache.CookieKey(token)
	expires := now.Add(time.Second * time.Duration(key.Timeout))
	cv := &cache.CookieValue{
		UserId:   user.Id,
		ExpireAt: int(expires.Unix()),
	}
	key.Set(cv)

	cookie := &http.Cookie{
		Name:     "token",
		Value:    token,
		Path:     "/",
		HttpOnly: true,
		Expires:  expires,
	}
	http.SetCookie(w, cookie)
}
